#include <iostream>
#include <unistd.h>
#include <vector>
#include <string>
#include "Thread.hpp"
#include "LockGuard.hpp"
using namespace std;
static int number = 1;
#define NUM 5
string getThreadname()
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "Thread-%d", number++);
    return buffer;
}
void Print()
{
    while (true)
    {
        cout << "Hello world" << endl;
        sleep(1);
    }
}

// 定义的锁也是全局的，这是共享的资源
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tickets = 10000; // 全局的资源

void getTicket(string name)
{
    while (1)
    {
        // pthread_mutex_lock(&mutex);        // 申请的锁也是原子性的，它是安全的
        LockGuard lockGuard(&mutex); // 局部变量，加锁和解锁
        if (tickets > 0)
        {
            usleep(100);
            cout << name << ", get a ticket: " << tickets << endl;
            tickets--;
            // pthread_mutex_unlock(&mutex);
        }
        else
        {
            // pthread_mutex_unlock(&mutex);

            break;
        }
    }
}
int main()
{
    string name1 = getThreadname();
    Thread<string> t1(name1, getTicket, name1);

    string name2 = getThreadname();
    Thread<string> t2(name2, getTicket, name2);

    string name3 = getThreadname();
    Thread<string> t3(name3, getTicket, name3);

    string name4 = getThreadname();
    Thread<string> t4(name4, getTicket, name4);
    t1.Start();
    t2.Start();
    t3.Start();
    t4.Start();

    t1.Join();
    t2.Join();
    t3.Join();
    t4.Join();

    // vector<Thread> Threads;
    // for (int i = 0; i < NUM; i++)
    // {
    //     Threads.push_back(Thread(getThreadname(), Print));
    // }

    // for (auto &t : Threads)
    // {
    //     cout << t.GetThreadName() << ", is running: " << t.Isrunning() << endl;
    // }

    // for (auto &t : Threads)
    // {
    //     cout << t.Start() << endl;
    // }

    // for (auto &t : Threads)
    // {
    //     cout << t.GetThreadName() << ", is running: " << t.Isrunning() << endl;
    // }

    // for (auto &t : Threads)
    // {
    //     cout << t.Join() << endl;
    // }

    return 0;
}